////////////////////////////////////////////////////////////////////////
// Copyright(c) 2016, All Rights Reserved
// Author:	FU YAN
// Created:2016/03/18
// Describe:
////////////////////////////////////////////////////////////////////////
#include "ByteStreamAssembler.h"

CByteStreamAssembler::CByteStreamAssembler()
{
	m_nPacketTotalSize = 0;
	m_nNotProcSize = 0;
}

CByteStreamAssembler::~CByteStreamAssembler()
{

}

CByteStream& CByteStreamAssembler::AssembleByteStream(char* pMsg, int nMsgSize, int& nConsumedSize, bool& bCompleted)
{
	bCompleted = ASSEMBLE_STATUS_FAILED;
	nConsumedSize = 0;

	if (pMsg == NULL)
	{
		return m_bs;
	}

	if (m_nNotProcSize == 0)
	{
		m_bs.Clear();
	}

	int nLeftSize = nMsgSize;
	char* pCurMsg = pMsg;
	while (nLeftSize > 0)
	{
		pCurMsg = pMsg + nMsgSize - nLeftSize;
		if (m_nNotProcSize == 0)//new msg
		{
			if (nLeftSize < sizeof(ByteStreamHead_t))
			{
				memcpy(&m_pRealHead, pCurMsg, nLeftSize);
				m_nNotProcSize = nLeftSize;
				nLeftSize = 0;
			}
			else
			{
				memcpy(&m_pRealHead, pCurMsg, sizeof(ByteStreamHead_t));
				nLeftSize -= sizeof(ByteStreamHead_t);
				m_nNotProcSize = sizeof(ByteStreamHead_t);
			}
		}
		else
		{
			if (m_nNotProcSize < sizeof(ByteStreamHead_t))
			{
				int nReadSize = sizeof(ByteStreamHead_t) - m_nNotProcSize;
				if (nLeftSize < nReadSize)
				{
					memcpy((((char*)(&m_pRealHead)) + m_nNotProcSize), pCurMsg, nLeftSize);
					m_nNotProcSize += nLeftSize;
					nLeftSize = 0;
				}
				else
				{
					memcpy(&m_pRealHead, pCurMsg, nReadSize);
					m_nNotProcSize += nReadSize;
					nLeftSize -= nReadSize;
				}
			}
			else
			{
				int nReadSize = m_pRealHead.usBodySize + sizeof(ByteStreamHead_t) - m_nNotProcSize;
				if (nLeftSize < nReadSize)
				{
					m_bs.WriteBytes(pCurMsg, nLeftSize);
					m_nNotProcSize += nLeftSize;
					nLeftSize = 0;
				}
				else
				{
					m_bs.WriteBytes(pCurMsg, nReadSize);
					m_bs.SetAction(m_pRealHead.usAction);
					bCompleted = ASSEMBLE_STATUS_SUCCEED;
					nLeftSize -= nReadSize;
					m_nNotProcSize = 0;
					break;
				}
			}
		}

		if (m_nNotProcSize >= sizeof(ByteStreamHead_t) && m_pRealHead.usBodySize + sizeof(ByteStreamHead_t) == m_nNotProcSize)
		{
			m_bs.SetAction(m_pRealHead.usAction);
			m_nNotProcSize = 0;
			bCompleted = ASSEMBLE_STATUS_SUCCEED;
			break;
		}
	}

	if (bCompleted == ASSEMBLE_STATUS_SUCCEED)
	{
		nConsumedSize = nMsgSize - nLeftSize;
	}

	return m_bs;
}
